﻿using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace yysAuxiliary.FS
{
    public abstract class BaseFs
    {
        /// <summary>
        /// 图片基地址
        /// </summary>
        private string picPath { get; } = AppDomain.CurrentDomain.BaseDirectory + "Pic";

        /// <summary>
        /// 发送消息委托
        /// </summary>
        protected Action<string> SendMsg;

        /// <summary>
        /// 前缀
        /// </summary>
        protected abstract string prefix { get; }

        public BaseFs(Action<string> SendMsg)
        {
            this.SendMsg = new Action<string>(p =>
            {
                SendMsg($"{prefix}{p}");
            });
        }

        /// <summary>
        /// 执行方法
        /// </summary>
        public abstract Task Run();


        #region NEW



        /// <summary>
        /// 判断当前画面在哪里
        /// </summary>
        /// <returns></returns>
        protected Data.GameInterface GetIndexGameInterface()
        {
            //判断是否在主界面
            var result = OperationPoint.IsExisit(OperationPoint.OperationType.JYT);
            if (result.isExisit)
            {
                Data.IndexGameInterface = Data.GameInterface.Main;
                SendMsg("interfaces");
                return Data.IndexGameInterface;
            }
            //判断是否在探索主界面
            result = OperationPoint.IsExisit(OperationPoint.OperationType.YuHun);
            if (result.isExisit)
            {
                Data.IndexGameInterface = Data.GameInterface.TS;
                SendMsg("interfaces");
                return Data.IndexGameInterface;
            }
            //判断是否在战斗中
            result = OperationPoint.IsExisit(OperationPoint.OperationType.ZDZT);
            if (result.isExisit)
            {
                Data.IndexGameInterface = Data.GameInterface.ZD;
                SendMsg("interfaces");
                return Data.IndexGameInterface;
            }

            Data.IndexGameInterface = Data.GameInterface.None;
            SendMsg("interfaces");
            return Data.IndexGameInterface;
        }

        /// <summary>
        /// 获取有效的游戏画面
        /// </summary>
        /// <returns></returns>
        protected async Task GetValidGameInterface()
        {
            SendMsg("去有效界面");
            while (GetIndexGameInterface() != Data.GameInterface.Main && GetIndexGameInterface() != Data.GameInterface.TS && Data.isRun)
            {
                //判断界面有没有返回按钮或者关闭按钮
                var result = OperationPoint.ExisitWithCheck(OperationPoint.OperationType.FanHui, 3);
                if (result)
                {
                    await Task.Delay(2000);
                    continue;
                }
                result = OperationPoint.ExisitWithCheck(OperationPoint.OperationType.GuanBi, 3);
                if (result)
                {
                    await Task.Delay(2000);
                    continue;
                }
                SendMsg("没有获取到有效画面,可以尝试手动跳转游戏到主界面");
                WinHelper.SendCheck(new Point(3, 33), 0);
                await Task.Delay(2000);
            }
        }

        /// <summary>
        /// 去探索
        /// </summary>
        /// <returns></returns>
        protected async Task<bool> GoTS()
        {
            if (GetIndexGameInterface() != Data.GameInterface.Main)
            {
                SendMsg("不在主界面");
                return false;
            }
            else
            {
                var result = OperationPoint.WhileCheck(10, 500, OperationPoint.OperationType.TanSuo, 10);
                if (!result)
                {
                    SendMsg("没有找到探索入口");
                    return false;
                }
                return true;
            }
        }



        #endregion


        /// <summary>
        /// 获取下一个功能
        /// </summary>
        protected void GetNextFS()
        {
            Data.actionedList.Add(Data.IndexFS);
            Data.fsList.Remove(Data.IndexFS);
            if (Data.fsList.Count == 0)
            {
                SendMsg($"当前一轮运行结束");
                if (ConfigData.Current.Loop <= Data.IndexLoop)
                {
                    Data.isRun = false;
                    return;
                }
                Data.IndexLoop++;
                Data.fsList.AddRange(Data.actionedList);
                Data.actionedList.Clear();
                Thread.Sleep(new Random().Next(5000, 10000));
            }
            Random r = new Random();
            Data.IndexFS = Data.fsList[r.Next(Data.fsList.Count)];
        }



        /// <summary>
        /// 图片包含 不存在就返回 0,0
        /// </summary>
        /// <param name="source">源图片</param>
        /// <param name="son">子图片需要包含验证</param>
        /// <returns></returns>
        protected Point PicContain(Bitmap source, Bitmap son)
        {
            Image<Bgr, byte> fu = new Image<Bgr, byte>(source);
            Image<Bgr, byte> zi = new Image<Bgr, byte>(son);
            Image<Gray, float> c = new Image<Gray, float>(fu.Width, fu.Height);
            c = fu.MatchTemplate(zi, TemplateMatchingType.CcorrNormed);
            double min = 0, max = 0;
            Point maxp = new Point(0, 0);
            Point minp = new Point(0, 0);
            CvInvoke.MinMaxLoc(c, ref min, ref max, ref minp, ref maxp);//max值需要大于0.98以上
            if (max > 0.98)
                return maxp;
            else
                return new Point(0, 0);
        }

        /// <summary>
        /// 图片包含 不存在就返回 0,0
        /// </summary>
        /// <param name="source">源图片</param>
        /// <param name="path">子图片地址</param>
        /// <returns></returns>
        protected Point PicContain(Bitmap source, string path)
        {
            Image<Bgr, byte> fu = new Image<Bgr, byte>(source);
            Image<Bgr, byte> zi = new Image<Bgr, byte>(path);
            Image<Gray, float> c = new Image<Gray, float>(fu.Width, fu.Height);
            c = fu.MatchTemplate(zi, TemplateMatchingType.CcorrNormed);
            double min = 0, max = 0;
            Point maxp = new Point(0, 0);
            Point minp = new Point(0, 0);
            CvInvoke.MinMaxLoc(c, ref min, ref max, ref minp, ref maxp);//max值需要大于0.98以上
            if (max > 0.98)
                return maxp;
            else
                return new Point(0, 0);
        }
    }
}
